#ifndef TELEGRAF_LIB_H
#define TELEGRAF_LIB_H

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <libpq-fe.h>
#include <map>
#include <cstring>
#include <ctime>    
#include <iomanip> 
#include <curl/curl.h>
#include <cstdlib> 

#ifdef _WIN32
#define TELEGRAF_LIB_EXPORT __declspec(dllexport)
#else
#define TELEGRAF_LIB_EXPORT
#endif

typedef int	DBCI_RETCODE;

#define	DBCI_OK					0
#define	DBCI_ERROR				-1
#define DBCIERR_INSERT_FAIL		-2
#define DBCIERR_CONNECT_FAIL	-3

struct DBConfigData 
{
	std::string ip;
	std::string  dbPort;
	std::string  httpPort;
	std::string user;
	std::string password;
	std::string defaultDB;
	std::string hisDB;

	DBConfigData()
		: ip("127.0.0.1"),
		dbPort("26257"),
		httpPort("8080"),
		user("root"),
		password("root123"),
		defaultDB("defaultdb"),
		hisDB("hisdb") {}
};

// 查询结果结构
struct QueryResult 
{
	bool success;
	std::string error_message;
	std::vector<std::map<std::string, std::string> > rows;
	std::vector<std::string> columns;
	int row_count;
	int column_count;

	QueryResult() : success(false), row_count(0), column_count(0) {}
};

class TELEGRAF_LIB_EXPORT DBConfig 
{
private:
	PGconn* db_connection_;
	std::string last_error_;
	int query_timeout_;
	DBConfigData data;

	// 字符串转换辅助函数
	std::string intToString(int value);
	std::string doubleToString(double value);
	std::string escapeString(const std::string& str);
	std::string escapeLiteral(const std::string& str);
	bool checkConnection();

public:
	// 连接状态枚举
	enum ConnectionStatus 
	{
		CONNECTION_OK,
		CONNECTION_FAILED,
		CONNECTION_BAD
	};

	// 构造函数/析构函数
	DBConfig(const std::string& filename = "kwdb_jdk.ini"); //默认读当前目录下的kwdb_jdk.ini文件，可指定
	~DBConfig();

	// 配置管理
	void load(const std::string& filename);
	void print() const ;
	std::string getbase64();

	// 时序数据库操作
	int login();	
	int insert(const std::string& postData, int mode = 0);

	// 关系数据库接口
	ConnectionStatus connectInitDB(const std::string& database = "");
	void disconnectFromDB();
	bool isDBConnected() const;

	// 数据库管理
	bool createDatabase(const std::string& db_name = "");
	bool useDatabase(const std::string& db_name = "");

	// 表管理
	bool tableExists(const std::string& table_name); 
	bool createTable(const std::string& table_name, 
		const std::vector<std::string>& columns,
		const std::string& primary_key = "");
	bool createTableIfNotExists(const std::string& table_name,
		const std::vector<std::string>& columns,
		const std::string& primary_key = "");
	bool dropTable(const std::string& table_name);

	// 数据操作
	bool insertToDB(const std::string& table_name, 
		const std::map<std::string, std::string>& data);
	bool batchInsertSingleBatch(const std::string& table_name, 
		const std::vector<std::map<std::string, std::string> >& data_list);
	bool batchInsertToDB(const std::string& table_name,
		const std::vector<std::map<std::string, std::string> >& data_list);

	// 查询操作
	QueryResult executeQuery(const std::string& sql);
	QueryResult selectFromDB(const std::string& table_name,
		const std::vector<std::string>& columns = std::vector<std::string>(),
		const std::string& where_clause = "",
		const std::string& order_by = "",
		int limit = -1);

	bool executeCommand(const std::string& sql);
	int getRowCount(const std::string& table_name, const std::string& where_clause = "");

	// 工具函数
	std::string getLastError() const;
	void setQueryTimeout(int seconds);
};

// JNI接口 - 单独放在条件编译中
#ifdef TELEGRAF_JNI_EXPORT
#include <jni.h>

extern "C" {
	// 实例管理
	TELEGRAF_LIB_EXPORT jlong JNICALL Java_TelegrafDB_createInstance(JNIEnv *, jobject, jstring);
	TELEGRAF_LIB_EXPORT void JNICALL Java_TelegrafDB_destroyInstance(JNIEnv *, jobject, jlong);

	// 配置相关
	TELEGRAF_LIB_EXPORT void JNICALL Java_TelegrafDB_loadConfig(JNIEnv *, jobject, jlong, jstring);
	TELEGRAF_LIB_EXPORT void JNICALL Java_TelegrafDB_printConfig(JNIEnv *, jobject, jlong);

	// 时序数据库操作
	TELEGRAF_LIB_EXPORT jint JNICALL Java_TelegrafDB_login(JNIEnv *, jobject, jlong);
	TELEGRAF_LIB_EXPORT jint JNICALL Java_TelegrafDB_insertData(JNIEnv *, jobject, jlong, jstring, jint);

	// 关系数据库操作
	TELEGRAF_LIB_EXPORT jint JNICALL Java_TelegrafDB_connectInitDB(JNIEnv *, jobject, jlong, jstring);
	TELEGRAF_LIB_EXPORT void JNICALL Java_TelegrafDB_disconnectFromDB(JNIEnv *, jobject, jlong);
	TELEGRAF_LIB_EXPORT jboolean JNICALL Java_TelegrafDB_isDBConnected(JNIEnv *, jobject, jlong);

	// 数据库管理
	TELEGRAF_LIB_EXPORT jboolean JNICALL Java_TelegrafDB_createDatabase(JNIEnv *, jobject, jlong, jstring);
	TELEGRAF_LIB_EXPORT jboolean JNICALL Java_TelegrafDB_useDatabase(JNIEnv *, jobject, jlong, jstring);

	// 表管理
	TELEGRAF_LIB_EXPORT jboolean JNICALL Java_TelegrafDB_tableExists(JNIEnv *, jobject, jlong, jstring);
	TELEGRAF_LIB_EXPORT jboolean JNICALL Java_TelegrafDB_createTable(JNIEnv *, jobject, jlong, jstring, jobjectArray, jstring);
	TELEGRAF_LIB_EXPORT jboolean JNICALL Java_TelegrafDB_createTableIfNotExists(JNIEnv *, jobject, jlong, jstring, jobjectArray, jstring);
	TELEGRAF_LIB_EXPORT jboolean JNICALL Java_TelegrafDB_dropTable(JNIEnv *, jobject, jlong, jstring);

	// 数据操作
	TELEGRAF_LIB_EXPORT jboolean JNICALL Java_TelegrafDB_insertToDB(JNIEnv *, jobject, jlong, jstring, jstring);
	TELEGRAF_LIB_EXPORT jboolean JNICALL Java_TelegrafDB_batchInsertToDB(JNIEnv *, jobject, jlong, jstring, jstring);

	// 查询操作
	TELEGRAF_LIB_EXPORT jstring JNICALL Java_TelegrafDB_executeQuery(JNIEnv *, jobject, jlong, jstring);
	TELEGRAF_LIB_EXPORT jstring JNICALL Java_TelegrafDB_selectFromDB(JNIEnv *, jobject, jlong, jstring, jobjectArray, jstring, jstring, jint);

	// 工具函数
	TELEGRAF_LIB_EXPORT jboolean JNICALL Java_TelegrafDB_executeCommand(JNIEnv *, jobject, jlong, jstring);
	TELEGRAF_LIB_EXPORT jint JNICALL Java_TelegrafDB_getRowCount(JNIEnv *, jobject, jlong, jstring, jstring);
	TELEGRAF_LIB_EXPORT jstring JNICALL Java_TelegrafDB_getLastError(JNIEnv *, jobject, jlong);
	TELEGRAF_LIB_EXPORT void JNICALL Java_TelegrafDB_setQueryTimeout(JNIEnv *, jobject, jlong, jint);
}
#endif

#endif // TELEGRAF_LIB_H